import os
from machine.config import Config

from subprocess import STDOUT, TimeoutExpired, check_output, CalledProcessError

MAX_LIMIT_BYTES_ERR_OUTPUT = 10000


def print_stdout_with_error(output: bytes):
    output = output.decode(encoding='UTF-8', errors='backslashreplace')
    output = (output[:MAX_LIMIT_BYTES_ERR_OUTPUT] +
              '...') if len(output) > MAX_LIMIT_BYTES_ERR_OUTPUT else output
    print(
        f"Console output before an error occurs (first {MAX_LIMIT_BYTES_ERR_OUTPUT} bytes):")
    print(output)


async def check_app_output():
    cfg = Config()
    os.chdir(cfg.work_directory)

    print(f"Checking for the executable file '{cfg.program_under_test}'")
    isExist = os.path.exists(cfg.program_under_test)
    assert isExist == True, "It was expected that CMake builds the executable file. Make sure that the executable file is correctly assembled using CMake."

    cmd = [cfg.program_under_test]

    try:
        print(f"Program execution starts. Arguments: '{cmd}'")
        output = check_output(cmd, stderr=STDOUT, timeout=cfg.action_timeout)
    except CalledProcessError as cpe:
        print_stdout_with_error(cpe.output)
        assert False, cpe
    except TimeoutExpired as te:
        print_stdout_with_error(te.output)
        assert False, "Program execution aborted due to timeout expiration. Check that you don't have endless program execution or waiting for data in the standard input stream."

    try:
        result = output.decode("utf-8")
    except UnicodeDecodeError as e:
        print(f"Error occurred during strict UTF-8 decoding: {e}")
        print(
            "Below is the console output in which the erroneous unencodable unicode is replaced with \\uNNNN escape sequence.")
        print_stdout_with_error(output)
        assert False, "The console output contains characters other than UTF-8 encoding. This led to an unsuccessful decoding of the console output."

    print("\nConsole output:")
    print(result)

    assert True
